////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2017-2018 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  camxbpsbpcpdpc20.h
/// @brief bpsbpcpdpc20 class declarations
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef CAMXBPSBPCPDPC20_H
#define CAMXBPSBPCPDPC20_H

#include "camxispiqmodule.h"
#include "iqcommondefs.h"
#include "pdpc_2_0_0.h"

CAMX_NAMESPACE_BEGIN

CAMX_BEGIN_PACKED

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief BPC PDPC register Configuration
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct BPSBPCPDPC20RegConfig0
{
    BPS_BPS_0_CLC_BPC_PDPC_PDPC_BLACK_LEVEL      PDPCBlackLevel;            ///< PDPC Black level
    BPS_BPS_0_CLC_BPC_PDPC_PDAF_HDR_EXP_RATIO    HDRExposureRatio;          ///< HDR exposure ratio
    BPS_BPS_0_CLC_BPC_PDPC_BAD_PIXEL_THRESHOLDS  BPCPixelThreshold;         ///< BPC Pixel threshold
    BPS_BPS_0_CLC_BPC_PDPC_BAD_PIXEL_DET_OFFSET  badPixelDetectionOffset;   ///< BPC/BCC detection offset
    BPS_BPS_0_CLC_BPC_PDPC_PDAF_RG_WB_GAIN       PDAFRGWhiteBalanceGain;    ///< PDAF R/G white balance gain
    BPS_BPS_0_CLC_BPC_PDPC_PDAF_BG_WB_GAIN       PDAFBGWhiteBalanceGain;    ///< PDAF B/G white balance gain
    BPS_BPS_0_CLC_BPC_PDPC_PDAF_GR_WB_GAIN       PDAFGRWhiteBalanceGain;    ///< PDAF G/R white balance gain
    BPS_BPS_0_CLC_BPC_PDPC_PDAF_GB_WB_GAIN       PDAFGBWhiteBalanceGain;    ///< PDAF G/B white balance gain
    BPS_BPS_0_CLC_BPC_PDPC_PDAF_LOC_OFFSET_CFG   PDAFLocationOffsetConfig;  ///< PDAF location offset config
    BPS_BPS_0_CLC_BPC_PDPC_PDAF_LOC_END_CFG      PDAFLocationEndConfig;     ///< PDAF location end config
} CAMX_PACKED;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief BPC PDPC register Configuration 1
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct BPSBPCPDPC20RegConfig1
{
    BPS_BPS_0_CLC_BPC_PDPC_BAD_PIXEL_DET_OFFSET_T2  badPixelDetectionOffsetT2;  ///< BPC/BCC detection offset for exposure T2
    BPS_BPS_0_CLC_BPC_PDPC_SATURATION_THRESHOLD     PDPCSaturationThreshold;    ///< PDPC saturation threshold
    BPS_BPS_0_CLC_BPC_PDPC_PDAF_TAB_OFFSET_CFG      PDAFTabOffsetConfig;        ///< PDAF tab offset config
} CAMX_PACKED;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief BPC PDPC register Configuration
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct BPSBPCPDPC20RegCmd
{
    BPSBPCPDPC20RegConfig0 config0;    ///< BPC/PDPC Config 0
    BPSBPCPDPC20RegConfig1 config1;    ///< BPC/PDPC Config 1
} CAMX_PACKED;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief BPC PDPC module Configuration
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct BPSBPCPDPC20ModuleConfig
{
    BPS_BPS_0_CLC_BPC_PDPC_MODULE_CFG  moduleConfig;   ///< BPCPDPC20 Module config
} CAMX_PACKED;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief BPC PDPC output data
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct BPSBPCPDPC20OutputData
{
    BPSBPCPDPC20RegCmd*       pRegCmd;          ///< Pointer to the BPCPDPC Register buffer
    BPSBPCPDPC20ModuleConfig* pModuleConfig;    ///< Ponter to  BPCPDPC Module config register
    UINT32*                   pDMIDataPtr;      ///< Pointer to the DMI table
} CAMX_PACKED;

CAMX_END_PACKED

static const UINT32 PDPCLUTBank0 = BPS_BPS_0_CLC_BPC_PDPC_DMI_LUT_BANK_CFG_BANK_SEL_LUT_BANK0;
static const UINT32 PDPCLUTBank1 = BPS_BPS_0_CLC_BPC_PDPC_DMI_LUT_BANK_CFG_BANK_SEL_LUT_BANK1;
static const UINT32 PDPCMaxLUT   = 1;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief BPS BPC PDPC 20 Class Implementation
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class BPSBPCPDPC20 final : public ISPIQModule
{
public:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Create
    ///
    /// @brief  Create BPSBPCPDPC20 Object
    ///
    /// @param  pCreateData Pointer to the BPSBPCPDPC20 Creation
    ///
    /// @return CamxResultSuccess if successful.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static CamxResult Create(
        BPSModuleCreateData* pCreateData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Initialize
    ///
    /// @brief  Initialize parameters
    ///
    /// @param  pInputData Pointer to the Inputdata
    ///
    /// @return CamxResultSuccess if successful
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult Initialize(
        const ISPInputData* pInputData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Execute
    ///
    /// @brief  Execute process capture request to configure module
    ///
    /// @param  pInputData Pointer to the ISP input data
    ///
    /// @return CamxResultSuccess if successful.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult Execute(
        ISPInputData* pInputData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ~BPSBPCPDPC20
    ///
    /// @brief  Destructor
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual ~BPSBPCPDPC20();

protected:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// BPSBPCPDPC20
    ///
    /// @brief  Constructor
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    BPSBPCPDPC20();

private:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// AllocateCommonLibraryData
    ///
    /// @brief  Allocate memory required for common library
    ///
    /// @return CamxResult success if the write operation is success
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult AllocateCommonLibraryData();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// DeallocateCommonLibraryData
    ///
    /// @brief  Deallocate memory required for common library
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID DeallocateCommonLibraryData();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// CheckDependenceChange
    ///
    /// @brief  Check to see if the Dependence Trigger Data Changed
    ///
    /// @param  pInputData Pointer to the ISP input data
    ///
    /// @return TRUE if dependencies met
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    BOOL CheckDependenceChange(
        ISPInputData* pInputData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// RunCalculation
    ///
    /// @brief   Calculate the Register Value
    ///
    /// @param   pInputData Pointer to the ISP input data
    ///
    /// @return  CamxResult Indicates if configure DMI and Registers was success or failure
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult RunCalculation(
        const ISPInputData* pInputData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// FetchDMIBuffer
    ///
    /// @brief  Fetching PDPC DMI LUT
    ///
    /// @return CamxResult Indicates if Fetching DMI was success or failure
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult FetchDMIBuffer();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// WriteLUTtoDMI
    ///
    /// @brief  Write Look up table data pointer into DMI header
    ///
    /// @param  pInputData Pointer to the ISP input data
    ///
    /// @return CamxResult Indicates if write to DMI header was success or failure
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult WriteLUTtoDMI(
        const ISPInputData* pInputData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// DumpRegConfig
    ///
    /// @brief  Print register configuration of BPC PDPC module for debug
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID DumpRegConfig() const;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// UpdateBPSInternalData
    ///
    /// @brief  Update BPS internal data
    ///
    /// @param  pInputData Pointer to the ISP input data
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID UpdateBPSInternalData(
        const ISPInputData* pInputData
        ) const;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// CreateCmdList
    ///
    /// @brief  Create the Command List
    ///
    /// @param  pInputData Pointer to the ISP input data
    ///
    /// @return CamxResult
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult CreateCmdList(
        const ISPInputData* pInputData);

    BPSBPCPDPC20(const BPSBPCPDPC20&)            = delete;     ///< Disallow the copy constructor
    BPSBPCPDPC20& operator=(const BPSBPCPDPC20&) = delete;     ///< Disallow assignment operator

    PDPC20IQInput                     m_dependenceData;        ///< Dependence Data for this Module
    BPSBPCPDPC20RegCmd                m_regCmd;                ///< Register list for BPC PDPC module
    CmdBufferManager*                 m_pLUTCmdBufferManager;  ///< Command buffer manager for all LUTs of BPC PDPC
    CmdBuffer*                        m_pLUTDMICmdBuffer;      ///< Command buffer for holding all LUTs
    BPSBPCPDPC20ModuleConfig          m_moduleConfig;          ///< Module configuration for BPCPDPC
    PixelFormat                       m_pixelFormat;           ///< Pixel Format from the sensor
    UINT32*                           m_pPDPCMaskLUT;          ///< Pointer to PDCP mask
    HotPixelModeValues                m_hotPixelMode;          ///< Hot pixel mode
    pdpc_2_0_0::chromatix_pdpc20Type* m_pChromatix;            ///< Pointer to tuning mode data
};

CAMX_NAMESPACE_END

#endif // CAMXBPSBPCPDPC20_H
